/*
 * BPlusTreeTest.cpp
 *
 *  Created on: 30 Sep, 2009
 *      Author: pankaj
 */

#include <iostream>
#include "BPlusTree.h"
#include "../common.h"
#include <stdlib.h>

#ifdef INDEX_ON
int main(int argc, char** argv)
{
	unsigned char keyformat[] = {LONG};
	BPlusTree::node root;
	root.level = 0;
	root.no_of_keys = 0;
	root.data.ldata.next.ptr = NULL;
	root.data.ldata.prev.ptr = NULL;
	root.parent.ptr = NULL;
	//root.indiv_nodes = NULL;

	int rootpage;
	BPlusTree *bpt = new BPlusTree(5,keyformat,1,&rootpage);
	BPlusTree index = *bpt;

	yadbms_common::rid r;
	r.pageno = 1;
	r.slotno = 0;
	//unsigned char temp[] = {'0','0','0','2','\0'};
	long *temp = new long;
	long ins;
	int pageno;
	int slotno;
	while(true)
	{
		std::cout<<"\n1. Display Headers\n2. Open Index\n3. Insert\n4. Insert Range\n";
		std::cout<<"5. Search All\n6. Range Search\n7. Delete\n8. Delete Range\n";
		std::cout<<"9. Display Tree Node-by-Node from Root\n10. Display Node\n11. Print Tree\n";
		std::cout<<"0.Exit \n";
		int ch1;
		std::cin>>ch1;
		switch(ch1)
		{
		case 0:
			return 0;
		case 1:
			index.printDetails();
			break;
		case 2:
			std::cout<<"Index Header Page No.:\n";
			cin>>rootpage;
			bpt->~BPlusTree();
			bpt = new BPlusTree(5,keyformat,1,rootpage);
			index = *bpt;
			break;
		case 3:
			std::cout<<"Number to insert:";

			std::cin>>ins;
			std::cout<<"Page Number to insert:";

			std::cin>>pageno;
			std::cout<<"Slot Number to insert:";

			std::cin>>slotno;
			//sprintf((char*)temp,"%8u",ins);
			*temp = ins;
			r.pageno = pageno;
			r.slotno = slotno;
			index.insert((unsigned char*)temp,r);
			//index.insert((unsigned char*)ins,r);
			//index.printTree();
			break;

		case 4:
			std::cout<<"First number of range";
			long st;
			std::cin>>st;
			std::cout<<"Last number of range";
			long lt;
			std::cin>>lt;

			while(st <= lt)
			{
				//sprintf((char*)temp,"%8u",st);
				*temp = st;
				//temp[3] = st + '0';
				r.pageno = st;
				r.slotno = st;
				st++;
				index.insert((unsigned char*)temp,r);
				//index.printTree();
			}
			//index.printTree();
			break;

		case 5:{
			std::vector<BPlusTree::searchresult> rids;
			std::cout<<"Number to search:";
			std::cin>>ins;
			//sprintf((char*)temp,"%8u",ins);
			*temp = ins;
			std::cout<<"Condition Select\n";
			std::cout<<"1. =\n2. <\n3. <=\n4. >\n5. >=\n";
			int cond;
			std::cin>>cond;
			int res;// = index.rangeSearch(temp,temp1,&rids,INCLUDE,INCLUDE);
			switch(cond)
			{
			case 1:
				res = index.rangeSearch((unsigned char*)temp,NULL,&rids,EQUAL,INCLUDE);
				break;
			case 2:
				res = index.rangeSearch(NULL,(unsigned char*)temp,&rids,EQUAL,EXCLUDE);
				break;
			case 3:
				res = index.rangeSearch(NULL,(unsigned char*)temp,&rids,EQUAL,INCLUDE);
				break;
			case 4:
				res = index.rangeSearch((unsigned char*)temp,NULL,&rids,EXCLUDE,EXCLUDE);
				break;
			case 5:
				res = index.rangeSearch((unsigned char*)temp,NULL,&rids,INCLUDE,INCLUDE);
				break;
			}
			std::cout<<"Search Result:"<<std::endl;
			std::cout<<"Count:"<<res<<std::endl;
			if(res > 0)
			{
				std::cout<<"Key\tRID\n";
				for(int i=0;i<res;i++)
				{
//					std::cout<<atoi((char*)rids[i].key)<<"\t["<<rids[i].record.pageno<<","<<rids[i].record.slotno<<"]\n";
					index.printKey(rids[i].key);
					std::cout<<"\t["<<rids[i].record.pageno<<","<<rids[i].record.slotno<<"]\n";
				}
				std::cout<<"\n";
			}

			break;
		}
		case 6:{
			std::cout<<"First Number to Search:";
			//ins;
			std::cin>>ins;
			//sprintf((char*)temp,"%8u",ins);
			*temp = ins;
			std::cout<<"Last Number to Search:";
			//ins;
			std::cin>>ins;
			//unsigned char temp1[8];
			long *temp1 = new long;
			*temp1 = ins;
			//sprintf((char*)temp1,"%8u",ins);
			std::vector<BPlusTree::searchresult> rids;
			//			int res = index.search(temp,&rids);
			int res = index.rangeSearch((unsigned char*)temp,(unsigned char*)temp1,&rids,INCLUDE,INCLUDE);
			std::cout<<"Search Result:"<<std::endl;
			std::cout<<"Count:"<<res<<std::endl;
			if(res > 0)
			{
				std::cout<<"Key\tRID\n";
				for(int i=0;i<res;i++)
				{
					index.printKey(rids[i].key);
					std::cout<<"\t["<<rids[i].record.pageno<<","<<rids[i].record.slotno<<"]\n";
				}
				std::cout<<"\n";
			}
			break;
		}
		case 7:
			std::cout<<"Number to Delete:";
			//ins;
			std::cin>>ins;
			std::cout<<"Page Number to Delete:";
			std::cin>>pageno;
			std::cout<<"Slot Number to Delete:";
			std::cin>>slotno;
			//sprintf((char*)temp,"%8u",ins);
			*temp = ins;
			r.pageno = pageno;
			r.slotno = slotno;
			index.deleteEntry((unsigned char*)temp,r);
			//			index.printTree();
			break;

		case 8:{
			//TODO: Delete Range
			std::cout<<"First number of range";
			long st;
			std::cin>>st;
			std::cout<<"Last number of range";
			long lt;
			std::cin>>lt;

			while(st <= lt)
			{
				//sprintf((char*)temp,"%8u",st);
				*temp = st;
				//temp[3] = st + '0';
				r.pageno = st;
				r.slotno = st;
				st++;
				index.deleteEntry((unsigned char*)temp,r);
//				index.printTree();
			}
			//index.printTree();
		}
		break;


		case 9:
			std::cout<<"Root - \n";
			index.printNode(index.getRoot());
			while(true)
			{
				std::cout<<"Enter Page Number(-1 to Go Back)-";
				int pgno;
				std::cin>>pgno;
				if(pgno == -1)
				{
					break;
				}
				BPlusTree::dp dpin;
				dpin.ptr = pgno;
				index.printNode(dpin);
			}
			break;
		case 10:
			std::cout<<"Enter Page Number-";
			int pgno;
			std::cin>>pgno;
			BPlusTree::dp dpin;
			dpin.ptr = pgno;
			index.printNode(dpin);
			break;

		case 11:
			index.printTree();
			break;

		default:
			std::cout<<"Invalid Input:\n";
			//return 0;




		}


	}
	std::cout<<"Done\n";
	return 0;
}
#endif
